import re
import threading
import traceback

import prettytable
import requests
import os

# http://www.kuwo.cn/api/v1/www/music/playUrl?mid=140897945&type=music&httpsStatus=1&reqId=da212430-bf1b-11ec-b451-85c1fde7239a


headers = {
    'Cookie': '_ga=GA1.2.1139504822.1650204819; _gid=GA1.2.372342311.1650204819; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1650204818,1650288581; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1650288817; kw_token=9FLWDW9WOCR',
    'csrf': '9FLWDW9WOCR',
    'Host': 'www.kuwo.cn',
    'Referer': 'http://www.kuwo.cn/rankList',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}


def create_directory(directory):  # 创建目录
    if not os.path.exists(directory):
        os.mkdir(directory)
        print(f"{directory}  文件夹创建成功")
        return 1
    else:
        print(f"{directory}  文件夹已经存在")
        return 0


def data_list_cl(url):  # 获取网页中歌曲的信息
    rel = requests.get(url, headers=headers)
    # print(rel.json())
    json_data = rel.json()
    data = json_data['data']['list']
    data_list = []
    tb = prettytable.PrettyTable()
    tb.field_names = ['序号', '歌名', '歌手', '专辑']
    count = 0

    for i in data:
        artist = i["artist"]  # 歌手名称
        rid = i["rid"]  # 音乐ID 
        album = i["album"]  # 专辑名称
        name = i["name"]  # 音乐名称
        data_list.append((name, rid, artist))  # 音乐名称 音乐ID 歌手名称
        tb.add_row([count, name, artist, album])
        count += 1
        # print(f"歌手：{artist}", f"音乐id:{rid}", f"音乐名称:{name}")
    print(tb)
    return data_list


def data_list_p(url):  # 获取排行榜网页中歌曲的信息
    rel = requests.get(url, headers=headers)
    # print(rel.json())
    json_data = rel.json()
    data = json_data['data']['musicList']
    data_list = []
    tb = prettytable.PrettyTable()
    tb.field_names = ['序号', '歌名', '歌手', '专辑']
    count = 0

    for i in data:
        artist = i["artist"]  # 歌手名称
        rid = i["rid"]  # 音乐ID
        album = i["album"]  # 专辑名称
        name = i["name"]  # 音乐名称
        data_list.append((name, rid, artist))  # 音乐名称 音乐ID 歌手名称
        tb.add_row([count, name, artist, album])
        count += 1
        # print(f"歌手：{artist}", f"音乐id:{rid}", f"音乐名称:{name}")
    print(tb)
    return data_list


def process_download_address(rid):  # 处理下载地址  rid:传入音乐的ID
    rid = rid
    url = f'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={rid}&type=convert_url3&br=320kmp3'
    rel = requests.get(url, headers=headers)
    data_str = rel.json()["data"]["url"]
    return data_str


def download_music(url, path, music_name, singer_name):  # 下载保存歌曲
    # url：音乐的下载地址 path：音乐的保存路径
    # music_name:音乐名称 singer_name:歌手名称
    if not os.path.exists(str(path) + str(music_name) + "---" + singer_name + '.mp3'):
        mu_data = requests.get(url).content
        with open(str(path) + str(music_name) + "---" + singer_name + '.mp3', mode='wb') as f:
            f.write(mu_data)
        print(str(path) + str(music_name) + "---" + singer_name + '.mp3' + "==================" + "下载成功")
    else:
        print(str(path) + str(music_name) + "---" + singer_name + '.mp3' + "===============已存在，你电脑的硬盘里！" )

def album_download_all():
    pass


def album_download_d():  # 按专辑ID下载
    #  http://www.kuwo.cn/api/www/artist/artistInfo?category=1&prefix=&pn=1&rn=102&httpsStatus=1&reqId=9b2ae0c0-c319-11ec-b2ca-33b7679c6488 华语男歌手
    #  http://www.kuwo.cn/api/www/artist/artistInfo?category=2&prefix=&pn=1&rn=102&httpsStatus=1&reqId=11508b60-c31a-11ec-b2ca-33b7679c6488 华语女歌手
    #  http://www.kuwo.cn/api/www/artist/artistInfo?category=3&prefix=&pn=1&rn=102&httpsStatus=1&reqId=37ec45c0-c31a-11ec-b2ca-33b7679c6488 华语组合
    #  http://www.kuwo.cn/api/www/artist/artistAlbum?artistid=336&pn=1&rn=28&httpsStatus=1&reqId=4772cfd0-c31c-11ec-99a4-6108ce969148 周杰伦专辑页面
    #  http://www.kuwo.cn/api/www/artist/artistMusic?artistid=336&pn=1&rn=30&httpsStatus=1&reqId=771e7c70-c31c-11ec-99a4-6108ce969148 周杰伦单曲页面
    #  http://www.kuwo.cn/api/www/artist/artistAlbum?artistid=47&pn=1&rn=28&httpsStatus=1&reqId=e1e26020-c31d-11ec-a2f5-71374e83e3b6  陈奕迅专辑页面
    #  http://www.kuwo.cn/api/www/search/searchArtistBykeyWord?key=周杰伦&pn=1&rn=1&httpsStatus=1&reqId=164759a0-c31f-11ec-876a-f55a5e6ca38f
    #  http://www.kuwo.cn/api/www/album/albumInfo?albumId=14466&pn=1&rn=30&httpsStatus=1&reqId=25c9b640-c327-11ec-9f87-57a9db9f0e79

    while True:
        name = input("请输入歌手名称(-1退出)：")
        if name == str(-1):
            break
        try:
            album_list = album_data(name.strip())
            create_directory(name)
            print(album_list)
            threads = []
            try:
                for i in album_list:
                    # print(i[0])
                    threads.append(threading.Thread(target=dxc_download, args=(name, i[0], i[1], i[2])))
                for thread in threads:
                    thread.start()
                for thread in threads:
                    thread.join()
            except:
                with open("log2.txt", "a") as f:
                    traceback.print_exc(file=f)
                continue

        except:
            with open("log1.txt", "a") as f:
                traceback.print_exc(file=f)
            continue


def dxc_download(name, album_name, album_id, jj):
    a = "&nbsp;"
    ralbum_name = re.sub(a, "", album_name)
    create_directory(name + "\\" + ralbum_name)
    urls = f"http://www.kuwo.cn/api/www/album/albumInfo?albumId={str(album_id)}&pn=1&rn=30&httpsStatus=1&reqId=25c9b640-c327-11ec-9f87-57a9db9f0e79"
    down_info_list = data_list_p(urls)
    # print(down_info_list)
    for o in down_info_list:
        music_json = process_download_address(o[1])
        download_music(music_json, name + "\\" + ralbum_name + "\\", o[0], o[2])
        with open(name + "\\" + ralbum_name + "\\专辑简介.txt", "w", encoding="utf-8") as f:
            f.write(re.sub(a, "", jj))
        # print(o[1], o[2], o[0])


def album_data(singer_name):  # 获取专辑信息
    data = singer_sid(str(singer_name))
    url = f"http://www.kuwo.cn/api/www/artist/artistAlbum?artistid={data[1]}&pn=1&rn=30&httpsStatus=1&reqId=771e7c70-c31c-11ec-99a4-6108ce969148"
    res = requests.get(url=url, headers=headers)
    aaa = res.json()["data"]["total"]
    url = f"http://www.kuwo.cn/api/www/artist/artistAlbum?artistid={data[1]}&pn=1&rn={aaa}&httpsStatus=1&reqId=771e7c70-c31c-11ec-99a4-6108ce969148"
    res = requests.get(url=url, headers=headers)
    album_l = res.json()["data"]["albumList"]
    album_list = []
    for i in album_l:
        album_name = i["album"]  # 专辑名称
        album_id = i["albumid"]  # 专辑ID
        album_info = i["albuminfo"]  # 专辑简介
        artist_name = i["artist"]  # 歌手名称
        album_list.append((album_name, album_id, album_info, artist_name))
    # print(album_list)
    # print(data)
    return album_list


def singer_sid(name):  # 歌手sid
    url = f"http://www.kuwo.cn/api/www/search/searchArtistBykeyWord?key={name}&pn=1&rn=1&httpsStatus=1&reqId=164759a0-c31f-11ec-876a-f55a5e6ca38f"
    res = requests.get(url=url, headers=headers)
    a = res.json()
    name = a["data"]["list"][0]["name"]
    sid = a["data"]["list"][0]["id"]
    return name, sid


def phb_download(pid):
    aa = 1
    while True:
        try:
            urls = f"http://www.kuwo.cn/api/www/bang/bang/musicList?bangId={pid}&pn={aa}&rn=30&httpsStatus=1&reqId=e785e4f0-c0b8-11ec-b647-3746e537ab87"
            down_info_list = data_list_p(urls)
            print("首页--h--,下一页--n--,上一页u--下载当前页全部--a--")
            input_index = input('请输入下载序号(-1退出)：')
            if input_index == str(-1):
                break
            elif input_index == "h" or input_index == "H":
                aa = 1
                continue
            elif input_index == "u" or input_index == "U":
                aa -= 1
                continue
            elif input_index == "n" or input_index == "N":
                aa += 1
                continue
            elif input_index == "a" or input_index == "A":
                for i in down_info_list:
                    music_json = process_download_address(i[1])
                    download_music(music_json, "./", i[0], i[2])
                    continue
            down_info = down_info_list[int(input_index)]
            rid = down_info[1]
            music_json = process_download_address(rid)
            download_music(music_json, "./", down_info[0], down_info[2])
        except:
            print("列表加载失败了！！！请稍等！！！，如果尝试加载不出来，请重启程序")


def main():
    """
    飙升榜     http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=93&pn=1&rn=30&httpsStatus=1&reqId=e785e4f0-c0b8-11ec-b647-3746e537ab87
    新歌榜     http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=17&pn=1&rn=30&httpsStatus=1&reqId=f2cbd490-c0b9-11ec-b647-3746e537ab87
    热歌榜     http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=16&pn=1&rn=30&httpsStatus=1&reqId=95613020-c0b9-11ec-b647-3746e537ab87
    抖音歌曲榜  http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=158&pn=1&rn=30&httpsStatus=1&reqId=146cfde0-c0ba-11ec-b647-3746e537ab87
    万物DJ榜   http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=176&pn=1&rn=30&httpsStatus=1&reqId=3bff9b60-c0ba-11ec-b647-3746e537ab87
    畅听榜     http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=145&pn=1&rn=30&httpsStatus=1&reqId=8d4e9430-c0ba-11ec-b897-119fb08f223c
    """
    while True:
        list_name = ["1.飙 升 榜", "2.新 歌 榜", "3.热 歌 榜", "4.抖音歌曲榜", "5.万物DJ榜", "6.畅 听 榜", "7.按音乐名称或歌手名称下载", "8.下载歌手的所有专辑"]
        for i in list_name:
            print(i)
        input_index = input("请选择(-1退出)：")
        if input_index == str(-1):
            break
        elif input_index == str(1):
            phb_download(93)
        elif input_index == str(2):
            phb_download(17)
        elif input_index == str(3):
            phb_download(16)
        elif input_index == str(4):
            phb_download(15)
        elif input_index == str(5):
            phb_download(176)
        elif input_index == str(6):
            phb_download(145)
        elif input_index == str(7):
            an_download()
        elif input_index == str(8):
            album_download_d()


def an_download():  # 按音乐名称或者歌手名称下载音乐
    while True:
        aaa = input("请输入想要下载的歌名或者歌手名称(-1退出)：")
        aa = 1
        if aaa == str(-1):
            break
        while True:
            try:
                urls = f"http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={aaa}&pn={aa}&rn=30&httpsStatus=1&reqId=b95ea390-bff6-11ec-896c-b5f0b7d4c6d4"
                down_info_list = data_list_cl(urls)
                print("首页--h--,下一页--n--,上一页u--下载当前页全部--a--")
                input_index = input('请输入下载序号(-1退出)：')
                if input_index == str(-1):
                    break
                elif input_index == "h" or input_index == "H":
                    aa = 1
                    continue
                elif input_index == "u" or input_index == "U":
                    aa -= 1
                    continue
                elif input_index == "n" or input_index == "N":
                    aa += 1
                    continue
                elif input_index == "a" or input_index == "A":
                    for i in down_info_list:
                        music_json = process_download_address(i[1])
                        download_music(music_json, "./", i[0], i[2])
                        continue
                down_info = down_info_list[int(input_index)]
                rid = down_info[1]
                music_json = process_download_address(rid)
                download_music(music_json, "./", down_info[0], down_info[2])
            except:
                print("列表加载失败了！！！请稍等！！！，如果尝试加载不出来，请重启程序")
                break


if __name__ == '__main__':

    main()
